﻿using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Configuration;
using System.Threading;
using S7.Net;
using S7.Net.Types;
using DateTime = System.DateTime;
using String = System.String;
using System.Threading.Tasks;
using YZJOSM.Models;
using YZJOSM.Utility;
using DataConverter;
using Microsoft.SqlServer.Server;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Xml.Linq;
using System.Linq;


namespace YZJOSM
{
    public partial class FrmMain : Form
    {
        private Plc plc = null;
        private bool ConnectionState = false;
        private CancellationTokenSource cts = null;
        public FrmMain()
        {
            InitializeComponent();
        }

        private string appPath = Application.StartupPath;

        private void Form1_Load(object sender, EventArgs e)
        {
            //string PlcIp = XmlHelper.ReadXmlFirst("PLC");
            //string startbit = XmlHelper.ReadXmlFirst("CollectionBit");
            //if(startbit== "true")
            //{
            //    StartCollectionData(PlcIp);
            //}

   
            dbname = XmlHelper.ReadXmlFirst("database");
           
            LoadSQName();
            this.ReportViewer1.RefreshReport();
            tabControl.ItemSize = new Size(0, 1);
            tabControl.Appearance = TabAppearance.Buttons;
            tabControl.SizeMode = TabSizeMode.Fixed;
          
            textBox3.Text = "";
            textBox5.Text = "";

            ReportViewer1.Visible = false;
            DT_EndDate.MaxDate = DateTime.Today;
            DT_BeginDate.MaxDate = DT_EndDate.Value;
            DT_BeginTime.Value = Convert.ToDateTime("00:00:00");
            DT_EndTime.Value = DateTime.Now;
            ToolStripStatusLabel3.Text = "";
            ToolStripStatusLabel1.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            btn_BatchSearch.Enabled = false;
            cmb_SampleTime.DataSource= XmlHelper.ReadXml("sampletime");
            cmb_SampleTime.SelectedIndex = 2;
        }

        private void Form1_Closing(object sender, EventArgs e)
        {
            //if (this.ConnectionState)
            //{
            //    this.plc?.Close();
            //    this.cts?.Cancel();
            //    this.ConnectionState = false;
            
            //}

        }



        #region 菜单栏
        private void Timer1_Tick(object sender, EventArgs e)
        {
            ToolStripStatusLabel1.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }

        private void DateTimePicker1_ValueChanged(object sender, EventArgs e)
        {
            if (DT_EndDate.Value < DT_BeginDate.Value)
            {
                DT_EndDate.Value = DT_BeginDate.Value;
            }
        }
        private void DateTimePicker2_ValueChanged(object sender, EventArgs e)
        {
            DT_BeginDate.MaxDate = DT_EndDate.Value;
        }

        private void 退出XToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.ConnectionState)
            {
                this.plc?.Close();
                this.cts?.Cancel();
                this.ConnectionState = false;

            }
            this.Close();
        }


        private void DateTimePicker3_ValueChanged(object sender, EventArgs e)
        {
            if (DT_EndTime.Value < DT_BeginTime.Value)
            {
                DT_EndTime.Value = DT_BeginTime.Value;
            }
        }

        private void DateTimePicker4_ValueChanged(object sender, EventArgs e)
        {
            DT_BeginTime.MaxDate = DT_EndTime.Value;
        }



        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            pictureBox3.Show();
            ReportViewer1.Hide();
            tabPage2.Hide();
            tabPage1.Show();
        }

        private void 数据库备份BToolStripMenuItem_Click(object sender, EventArgs e)
        {

            textBox3.Text = "";
            textBox4.Text = "";
            textBox5.Text = "";
            textBox6.Text = "";
            lst_DataBase.Items.Clear();
            tabPage1.Hide();
            tabPage2.Show();

        }


        public object Product_InfoTableAdapter { get; private set; }

        /// <summary>
        /// 选择还原数据库文件目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog TargetAdd = new FolderBrowserDialog();
            TargetAdd.Description = "请选择数据库备份所在的目录";
            TargetAdd.RootFolder = Environment.SpecialFolder.MyComputer;
            TargetAdd.ShowNewFolderButton = false;
            if (TargetAdd.ShowDialog() == DialogResult.OK)
            {
                lst_DataBase.Items.Clear();
                lst_DataBase.SelectedItem = null;
                textBox6.Text = "";
                textBox5.Text = TargetAdd.SelectedPath;
                String[] Files = Directory.GetFiles(textBox5.Text);
                foreach (string str in Files)
                    if (str.Substring(str.LastIndexOf('.') + 1).ToLower() == "bak")
                        lst_DataBase.Items.Add(str);
            }
        }
        /// <summary>
        /// 备份数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            textBox4.Text = BackupsFile;
            if (txt_BackName.Text == "" || textBox3.Text == "")
            {
                MessageBox.Show("请填写正确的备份路径及文件名！", "提示框");
            }
            else
            {
                if (!File.Exists(BackupsFile))
                {

                    String Sql = "backup database " + dbname + " to disk='" + BackupsFile + "' with Init";
                    SQLHelper.ExecuteNonQuery(Sql);
                    MessageBox.Show("你已经成功备份当前数据！", "系统消息");
                }
                else
                {
                    MessageBox.Show("备份失败，该文件名已存在！", "提示框");
                }
            }
        }
        String BackupsFile = "";
        String RestoreFile = "";
        String dbname = "";
        /// <summary>
        /// 选择备份数据库目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog TargetAdd = new FolderBrowserDialog();
            TargetAdd.Description = "请选择数据库备份的目标位置";
            TargetAdd.RootFolder = Environment.SpecialFolder.MyComputer;
            TargetAdd.ShowNewFolderButton = false;
            if (TargetAdd.ShowDialog() == DialogResult.OK)
            {
                textBox3.Text = TargetAdd.SelectedPath;
                BackupsFile = textBox3.Text + "\\" + txt_BackName.Text + "_" + DateTime.Now.ToString("yyyyMMddhhmm") + ".bak";
                textBox4.Text = BackupsFile;
            }
        }
        /// <summary>
        /// 还原数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            if (textBox5.Text == "" || textBox6.Text == "")
            {
                MessageBox.Show("请选择正确的还原路径及文件名！", "提示框");
            }
            else
            {
                if (File.Exists(RestoreFile))
                {

                    String Sql = ("use master " +
                    "alter database " + dbname + " set offline with rollback immediate " +
                    "restore database " + dbname + " from disk = '" + RestoreFile + "' with Replace " +
                    "alter database " + dbname + " set online with rollback immediate");
                    SQLHelper.ExecuteNonQuery(Sql);
                    MessageBox.Show("你已经成功还原选定的数据！", "系统消息");

                }
                else
                {
                    MessageBox.Show("还原失败，该路径文件名不存在！", "提示框");
                }
            }
        }

        private void txt_BackName_TextChanged(object sender, EventArgs e)
        {
            BackupsFile = textBox3.Text + "\\" + txt_BackName.Text + "_" + DateTime.Now.ToString("yyyyMMddhhmm") + ".bak";
            textBox4.Text = BackupsFile;
        }

        private void lst_DataBase_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lst_DataBase.SelectedItem != null)
            {
                RestoreFile = lst_DataBase.SelectedItem.ToString();
                textBox6.Text = RestoreFile;
            }
        }
        #endregion


        /// <summary>
        /// 根据报表类型查询批号，分CIP,SIP两类
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_BatchSearch_Click(object sender, EventArgs e)
        {
            ReportViewer1.Visible = false;
            BatchBases batchNameBase = (BatchBases)cmb_Batch.SelectedItem;
            string sql = "select * from tblData where reportname ='" + batchNameBase.reportname + "'";
            //获取不重复的1s数据
            DataTable dtChart = GetDistinctSelf(SQLHelper.ExecuteDataTable(sql),"strTime");
            if (dtChart == null)
            {
                MessageBox.Show("没有消毒段数据");
                return;
            }
                
            sql = "select * from tblData where reportname ='" + batchNameBase.reportname + "'and stepNo=1";
            
            DataTable dtAvg = GetDistinctSelf(SQLHelper.ExecuteDataTable(sql), "strTime");
            if (dtAvg == null)
            {
                MessageBox.Show("没有消毒段数据");
                return;
            }
          
            string StartTime = dtChart.Compute("MIN(strTime)", "true").ToString();
            string StopTime = dtChart.Compute("MAX(strTime)", "true").ToString(); 
            string SipStart = dtChart.Compute("Min(strTime)", "stepNo=1").ToString();
            string SipStop = dtChart.Compute("Max(strTime)", "stepNo=1").ToString();
            if(SipStart==""|SipStop=="")
            {
                MessageBox.Show("没有消毒段数据");
                return;              
            }
         
            int startIndex = (int)Convert.ToDateTime(SipStart).Subtract(Convert.ToDateTime(StartTime)).TotalSeconds;
            int stopIndex = (int)Convert.ToDateTime(SipStop).Subtract(Convert.ToDateTime(StartTime)).TotalSeconds;


         
//详细数据表
            DataTable dtList = new DataTable();
            string SampleTime = cmb_SampleTime.SelectedItem.ToString();
            sql = "Select * from tblData where strTime in"+
                " (select distinct strTime from tblData where reportname ='" + batchNameBase.reportname + "' And(DATEDIFF(s, convert(nvarchar(20), strTime, 720), convert(nvarchar(20), '"+ StartTime+"', 720)) %"+ SampleTime + ")=0 " +
                "union select max(strtime)strtime from tblData where reportname ='" + batchNameBase.reportname + "')";
            dtList = GetDistinctSelf(SQLHelper.ExecuteDataTable(sql), "strTime");
            if(dtList==null)
            {
                MessageBox.Show("没有消毒段数据");
                return;
            }
            if (dtChart.Rows.Count > 0)
            {
                
                string[] startdate = StartTime.Split(' ');
                List<ReportParameter> list = new List<ReportParameter>();
                list.Clear();


                list.Add(new ReportParameter("BatchString", batchNameBase.reportname));
                list.Add(new ReportParameter("ReportType", batchNameBase.reportType.ToString()));

                list.Add(new ReportParameter("StartIndex", startIndex.ToString()));//灭菌开始的索引
                list.Add(new ReportParameter("StopIndex", stopIndex.ToString()));//灭菌结束的索引
                list.Add(new ReportParameter("StartTime", Convert.ToDateTime(StartTime).ToString("yyyy-MM-dd HH:mm:ss")));//灭菌开始的时间
                list.Add(new ReportParameter("StopTime", Convert.ToDateTime(StopTime).ToString("yyyy-MM-dd HH:mm:ss")));//灭菌结束的时间

                list.Add(new ReportParameter("SipStart", Convert.ToDateTime(SipStart).ToString("yyyy-MM-dd HH:mm:ss")));//灭菌开始的时间
                list.Add(new ReportParameter("SipStop", Convert.ToDateTime(SipStop).ToString("yyyy-MM-dd HH:mm:ss")));//灭菌结束的时间
             

                list.Add(new ReportParameter("Date", Convert.ToDateTime(startdate[0]).ToString("yyyy-MM-dd")));//灭菌日期
                list.Add(new ReportParameter("DetailDisplay", (this.checkBox1.Checked == true) ? "true" : "false"));


                
                ReportViewer1.Visible = true;

                ReportViewer1.ProcessingMode = ProcessingMode.Local;
                ReportViewer1.LocalReport.DataSources.Clear();
                ReportViewer1.LocalReport.ReportPath = this.appPath + "\\ReportSIP.rdlc";
                ReportViewer1.LocalReport.SetParameters(list);
                //温度详细数据
                ReportViewer1.LocalReport.DataSources.Add(new ReportDataSource("dtList", dtList));
                //计算平均温度
                ReportViewer1.LocalReport.DataSources.Add(new ReportDataSource("dtAvg", dtAvg));
                //曲线
                ReportViewer1.LocalReport.DataSources.Add(new ReportDataSource("dtChart", dtChart));
                ReportViewer1.RefreshReport();
            }
            else
            {
                pictureBox3.Show();
                ReportViewer1.Hide();
                tabPage2.Hide();
                tabPage1.Show();
                MessageBox.Show("没有查到生产数据");
            }
        }


        /// <summary>
        /// 获取SQ_Name
        /// </summary>
        /// <param name="Sql"></param>
        private void LoadSQName()
        {         
            cmb_TankName.DataSource = XmlHelper.ReadXml("reportType");
            cmb_TankName.SelectedIndex = 0;
      }
        
        private void StartCollectionData(string PlcIp)
        {
            if (!ConnectionState)
            {
                try
                {
                    this.plc = new Plc(CpuType.S7300, PlcIp, 0, 2);
                    plc.Open();
                }
                catch
                {
                    return;
                }
                this.ConnectionState = true;
                //开启线程
                cts = new CancellationTokenSource();
                Task.Run(new Action(() =>
                {
                    ReadData();
                }), cts.Token);

            }
            else
            {

            }
        }


        private void ReadData()
        {
            //数据读取
            while (!cts.IsCancellationRequested)
            {
                try
                {                   
                    bool startBit =(bool) plc.Read("DB400.DBX0.0");
                    if (startBit)
                    {
                        string strTime = DateTime.Now.ToString(("yyyy-MM-dd HH:mm:ss"));
                       // plc.Write("DB400.DBX0.0", false);
                        byte[] result = plc.ReadBytes(S7.Net.DataType.DataBlock, 400, 0, 66);
                        
                        //string strTime = StringLib.GetSiemensStringFromByteArray(result, 2, 20);
                        string reportName = StringLib.GetSiemensStringFromByteArray(result, 24, 20);

                        short reportType = ShortLib.GetShortFromByteArray(result, 46);
                        short stepNo = ShortLib.GetShortFromByteArray(result, 48);
                        float tt1 = FloatLib.GetFloatFromByteArray(result, 50);
                        float tt2 = FloatLib.GetFloatFromByteArray(result, 54);
                        string sql = "insert into tblData(strTime,reportName,reportType,tt1,tt2,stepNo) VALUES ('" + strTime + "','" + reportName + "'," + reportType.ToString() + "," + tt1.ToString() + "," + tt2.ToString() + "," + stepNo.ToString() + ")";
                        //MessageBox.Show(sql);
                        SQLHelper.ExecuteNonQuery(sql);
                    }
                }
                catch
                {
                }
                Thread.Sleep(1000);
            }
        }

        private void GetBatchNameBasesListAll<T>(string sql)
        {
            List<T> batchNameBases = new List<T>();
            DataTable dt = SQLHelper.ExecuteDataTable(sql);
            foreach (DataRow dr in dt.Rows)
            {
                batchNameBases.Add(dr.DataRowToModel<T>());//反射
            }
            cmb_Batch.DataSource = batchNameBases;
            cmb_Batch.DisplayMember = "reportname";
            if (batchNameBases.Count > 0)
            {
                btn_BatchSearch.Enabled = true;
            }
            else
            {
                MessageBox.Show("没有查到批号信息");
            }
        }
        /// <summary>
        /// 查询批号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ReportSearch_Click(object sender, EventArgs e)
        {
            ReportViewer1.Visible = false;
            int reportType = (int)cmb_TankName.SelectedIndex+1;
            string SQLTime = " where (strTime between '" + DT_BeginDate.Value.ToString("yyyy-MM-dd") + " " + DT_BeginTime.Value.ToString("HH:mm:ss") + "' And '" + DT_EndDate.Value.ToString("yyyy-MM-dd") + " " + DT_EndTime.Value.ToString("HH:mm:ss") + "')";
            string Sql = "SELECT DISTINCT REPORTNAME,reportType FROM tblData where reporttype=" + reportType+ " Order by REPORTNAME";
            GetBatchNameBasesListAll<BatchBases>(Sql);
        }
        /// <summary>
        /// 对DataTable中，针对某一列去除重复值
        /// </summary>
        /// <param name="SourceDt"></param>
        /// <param name="filedName"></param>
        /// <returns></returns>
        public DataTable GetDistinctSelf(DataTable SourceDt, string filedName)
        {
            //for (int i = SourceDt.Rows.Count - 2; i > 0; i--)
            //{
            //    DataRow[] rows = SourceDt.Select(string.Format("{0}='{1}'", filedName, SourceDt.Rows[i][filedName]));
            //    if (rows.Length > 1)
            //    {
            //        SourceDt.Rows.RemoveAt(i);
            //    }
            //}
            //return SourceDt
            if(SourceDt.Rows.Count > 0)
            {
                return SourceDt.AsEnumerable().Cast<DataRow>().GroupBy(p => p.Field<string>(filedName)).Select(p => p.FirstOrDefault()).CopyToDataTable();
            }
            return null;
            
        }


    }

}

